﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.Publishing.Administration;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Diagnostics;
using Microsoft.SharePoint.Deployment;
using Microsoft.SharePoint.Utilities;
using System.Reflection;
using Microsoft.SharePoint.Administration;
using System.Web.UI.HtmlControls;
using Microsoft.SharePoint.WebControls;
using System.Web;

namespace Macaw.Moss2007.ContentChangesOverviewSolution
{
    public class ChangesOverview : Microsoft.SharePoint.WebControls.LayoutsPageBase
    {

        protected Label lblNoChanges;
        protected SPGridView gvChanges;
        protected ChangeTypesMenuButton menuChangeTypes;
        protected ObjectTypesMenuButton menuObjecTypes;
        protected CDPathMenuButton menuCDPath;
        protected StartTimeMenuButton menuStarttime;

        private int index = 0;


        protected override void OnLoad(EventArgs e)
        {
            if (!IsPostBack)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate
{

    Populate();
});
            }


            base.OnLoad(e);
        }

        private void Populate()
        {
            SPChangeQuery query = new SPChangeQuery(true, true);

            using (SPSite site = new SPSite(SPContext.Current.Site.ID))
            {


                if (!menuCDPath.CDPath.Equals(Guid.Empty))
                {
                    ContentDeploymentPath cdpath = ContentDeploymentPath.GetInstance(menuCDPath.CDPath);

                    foreach (DeploymentStatus status in cdpath.DeploymentStatusDictionary.Values)
                    {
                        if (status.ObjectType == SPDeploymentObjectType.Site && site.ID.Equals(status.Id))
                        {
                            SPChangeToken changetoken = new SPChangeToken(status.LastExportChangeToken);
                            query.ChangeTokenStart = changetoken;
                        }
                    }
                }

                if (menuStarttime.Ago != StartTimeMenuButton.EnumAgo.All)
                {
                    DateTime agotime = DateTime.MinValue;
                    switch (menuStarttime.Ago)
                    {
                        case StartTimeMenuButton.EnumAgo.OneDayAgo:
                            agotime = DateTime.UtcNow.AddDays(-1);
                            break;
                        case StartTimeMenuButton.EnumAgo.OneHourAgo:
                            agotime = DateTime.UtcNow.AddHours(-1);
                            break;
                        case StartTimeMenuButton.EnumAgo.OneMonthAgo:
                            agotime = DateTime.UtcNow.AddMonths(-1);
                            break;
                        case StartTimeMenuButton.EnumAgo.OneWeekAgo:
                            agotime = DateTime.UtcNow.AddDays(-7);
                            break;
                        case StartTimeMenuButton.EnumAgo.TwoWeeksAgo:
                            agotime = DateTime.UtcNow.AddDays(-14);
                            break;

                    }
                    query.ChangeTokenStart = new SPChangeToken(SPChangeCollection.CollectionScope.Site, site.ID, agotime);
                }



                query.Alert = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.Alert) != 0;
                query.ContentType = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.ContentType) != 0;
                query.Field = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.Field) != 0;
                query.File = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.File) != 0;
                query.Folder = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.Folder) != 0;
                query.Group = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.Group) != 0;
                query.Item = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.Item) != 0;
                query.List = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.List) != 0;
                query.Navigation = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.Navigation) != 0;
                query.SecurityPolicy = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.SecurityPolicy) != 0;
                query.Site = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.Site) != 0;
                query.User = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.User) != 0;
                query.View = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.View) != 0;
                query.Web = (menuObjecTypes.CheckedMenuItemIds & ObjectTypesMenuButton.enumObjectTypes.Web) != 0;


                query.Add = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.Add) != 0;
                query.Delete = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.Delete) != 0;
                query.Move = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.Move) != 0;
                query.Navigation = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.Navigation) != 0;
                query.GroupMembershipAdd = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.GroupMembershipAdd) != 0;
                query.GroupMembershipDelete = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.GroupMembershipDelete) != 0;
                query.RoleAssignmentAdd = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.RoleAssignmentAdd) != 0;
                query.RoleAssignmentDelete = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.RoleAssignmentDelete) != 0;
                query.RoleDefinitionAdd = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.RoleDefinitionAdd) != 0;
                query.RoleDefinitionDelete = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.RoleDefinitionDelete) != 0;
                query.RoleDefinitionUpdate = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.RoleDefinitionUpdate) != 0;
                query.Rename = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.Rename) != 0;
                query.Restore = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.Restore) != 0;
                query.SystemUpdate = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.SystemUpdate) != 0;
                query.Update = (menuChangeTypes.CheckedMenuItemIds & ChangeTypesMenuButton.enumChangeTypes.Update) != 0;

                List<SPChange> changes2 = new List<SPChange>();
                SPChangeCollection changes = null;

                do
                {
                    try
                    {
                        changes = site.GetChanges(query);
                    }
                    catch
                    {
                        // An error may occur if the ChangeTokenStart is a time prior to the start of the ChangeLog. Fix it, by quering all.
                        if (query.ChangeTokenStart != null)
                        {
                            query.ChangeTokenStart = null;
                            changes = site.GetChanges(query);
                        }
                    }
                    foreach (SPChange change in changes) changes2.Add(change);
                    query.ChangeTokenStart = changes.LastChangeToken;
                } while (changes.Count == SPChangeCollection.CountLimit);


                if (changes != null && changes.Count > 0)
                {
                    gvChanges.DataSource = changes2;
                    gvChanges.DataBind();

                    gvChanges.Visible = true;

                    lblNoChanges.Visible = false;
                }
                else
                {
                    gvChanges.Visible = false;
                    lblNoChanges.Visible = true;
                }
            }
        }


        /// <summary>
        /// Click event handler of Refresh-button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void btnRefresh_Click(object sender, EventArgs e)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate
            {

                Populate();
            });
        }



        public void gvChanges_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                index++;

                SPChange change = (SPChange)e.Row.DataItem;

                Label lblIndex = (Label)e.Row.Controls[0].FindControl("lblIndex");
                lblIndex.Text = index.ToString();
                lblIndex.ToolTip = change.ChangeToken.ToString();

                Label lblTime = (Label)e.Row.Controls[1].FindControl("lblTime");
                lblTime.Text = change.Time.ToLocalTime().ToString();

                Label lblChangeType = (Label)e.Row.Controls[2].FindControl("lblChangeType");
                lblChangeType.Text = change.ChangeType.ToString();

                Label lblType = (Label)e.Row.Controls[3].FindControl("lblType");
                lblType.Text = change.GetType().Name.Replace("SPChange", "");

                HyperLink hlItem = (HyperLink)e.Row.Controls[4].FindControl("hlItem");

                Label lblUser = (Label)e.Row.Controls[5].FindControl("lblUser");
                lblUser.Text = "<unknown>";

                System.Web.Caching.Cache cache = HttpContext.Current.Cache;
                using (SPSite site = new SPSite(change.SiteId))
                {
                    try
                    {
                        string key = string.Format("change_{0}", change.ChangeToken.ToString());
                        RetrievedChangeInfo changeinfo = (RetrievedChangeInfo ) cache.Get(key);
                        if (changeinfo==null)
                        {
                            changeinfo = SPChangeHelper.GetChangeInfo(change, site);
                            cache.Add(key, changeinfo, null, DateTime.MaxValue, new TimeSpan(0, 10, 0), System.Web.Caching.CacheItemPriority.Low, null);
                        }
                        hlItem.Text = changeinfo.objectTitle;
                        hlItem.NavigateUrl = changeinfo.objectUrl;
                        lblUser.Text = changeinfo.user;

                    }
                    catch (Exception ex)
                    {
                        // Supress exceptions
                    }
                }
            }
        }

    }
}
